package org.mindrive.system.service.schedule;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.mindrive.system.collection.schedule.ScheduleDetailsEntity;
import org.mindrive.system.collection.schedule.ScheduleEntity;
import org.mindrive.system.collection.system.UserEntity;
import org.mindrive.system.parameter.schedule.ScheduleParameter;
import org.mindrive.system.parameter.schedule.ScheduleSearchParameter;
import org.mindrive.system.dto.ScheduleDTO;
import org.mindrive.system.service.BaseConstant;
import org.mindrive.system.service.BaseService;
import org.mindrive.system.util.DateTimeUtil;
import org.mindrive.system.util.DateWeekUtil;
import org.mindrive.system.util.TemplateExcelUtils;
import org.springframework.beans.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.IsoFields;
import java.util.Arrays;
import static java.util.stream.Collectors.toList;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * (Schedule)表服务接口
 *
 * @author maweihong
 * @since 2023-12-11 09:41:41
 */
@Service
@Slf4j
public class ScheduleService extends BaseService {

    private static final String importPeople = "韩蓉荟";

    private static final String normalPeople = "高海军,白元和,杨荻,刘铁生,王新宇,冯连武,张丛峰,岳向东,刘姜";


    /**
     * 查询(可分页)
     * @Author mwh
     * @Date 13:48 2023/8/12
     * @Param [parameter]
     * @return java.util.Map<java.lang.String,java.lang.Object>
     **/
    public Map<String, Object> search(ScheduleSearchParameter parameter) {
        QueryWrapper<ScheduleEntity> query = new QueryWrapper<ScheduleEntity>();
//        query.eq("zhuang_tai" , "0");
                
        if (parameter.getType() != null && !"".equals(parameter.getType())) {
            query.eq("TYPE" , parameter.getType());
        }
                
        if (parameter.getScheName() != null && !"".equals(parameter.getScheName())) {
            query.like("SCHE_NAME" , parameter.getScheName());
        }

        if (parameter.getBeginTime() != null && !"".equals(parameter.getBeginTime())) {
            query.like("BEGIN_TIME" , parameter.getBeginTime());
        }
                
        int count = (int) scheduleDao.count(query);
        query.orderByAsc(CREATED_AT);
        
        List<ScheduleEntity> list = new ArrayList<ScheduleEntity>();
        List<ScheduleDTO> listDto = new ArrayList<ScheduleDTO>();
        Page<ScheduleEntity> page = page(ScheduleEntity.class, parameter.getPageSize(), parameter.getCurrentPage());
        if (page == null) {
            list = scheduleDao.list(query);
        } else {
            scheduleDao.page(page, query);
            list = page.getRecords();
        }
        
        for (ScheduleEntity schedule : list){
            ScheduleDTO scheduleDTO = new ScheduleDTO();
            BeanUtils.copyProperties(schedule , scheduleDTO);
            listDto.add(scheduleDTO);
        }
        
        Map<String, Object> result = new HashMap<String, Object>();
        result.put(COUNT, count);
        result.put(LIST, listDto);
        return result;
    }

    public ScheduleEntity detail(String id) {
        return scheduleDao.getById(id);
    }

    public void dingShiCreate(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfByName = new SimpleDateFormat("yyyy年MM月");
        Calendar calendar = Calendar.getInstance();
//        calendar.set(Calendar.DAY_OF_MONTH,25);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
        if (dayOfWeek == Calendar.MONDAY){
            //是周一
            final List<ScheduleEntity> scheduleList = scheduleDao.list(new QueryWrapper<ScheduleEntity>().eq("BEGIN_TIME", sdf.format(new Date())));
            if (scheduleList.isEmpty()){
                //生成主要领导日程
                ScheduleEntity schedule = new ScheduleEntity();
                schedule.setBeginTime(sdf.format(new Date()));
                schedule.setScheName(sdfByName.format(new Date())+"第"+weekOfMonth+"周主要领导日程");
                schedule.setType(0);
                schedule.setCreator("auto");
                schedule.setCreatedAt(new Date());
                scheduleDao.save(schedule);
                final String[] importPeopleList = importPeople.split(",");
                for (String people : importPeopleList){
                    ScheduleDetailsEntity sde = new ScheduleDetailsEntity();
                    sde.setScheName(people);
                    sde.setScheNameOperHist("");
                    sde.setScheduleId(schedule.getId());
                    sde.setMonValue("");
                    sde.setMonValueOperHist("");
                    sde.setTuesValue("");
                    sde.setTuesValueOperHist("");
                    sde.setWedValue("");
                    sde.setWedValueOperHist("");
                    sde.setThursValue("");
                    sde.setThursValueOperHist("");
                    sde.setFriValue("");
                    sde.setFriValueOperHist("");
                    sde.setSatValue("");
                    sde.setSatValueOperHist("");
                    sde.setSunValue("");
                    sde.setSunValueOperHist("");
                    sde.setCreator("auto");
                    sde.setCreatedAt(new Date());
                    scheduleDetailsDao.save(sde);
                }
                //生成其他领导日程
                ScheduleEntity scheduleQiTa = new ScheduleEntity();
                scheduleQiTa.setBeginTime(sdf.format(new Date()));
                scheduleQiTa.setScheName(sdfByName.format(new Date())+"第"+weekOfMonth+"周其他领导日程");
                scheduleQiTa.setType(1);
                scheduleQiTa.setCreator("auto");
                scheduleQiTa.setCreatedAt(new Date());
                scheduleDao.save(scheduleQiTa);
                final String[] normalPeopleList = normalPeople.split(",");
                for (String people : normalPeopleList){
                    ScheduleDetailsEntity sde = new ScheduleDetailsEntity();
                    sde.setScheName(people);
                    sde.setScheNameOperHist("");
                    sde.setScheduleId(scheduleQiTa.getId());
                    sde.setMonValue("");
                    sde.setMonValueOperHist("");
                    sde.setTuesValue("");
                    sde.setTuesValueOperHist("");
                    sde.setWedValue("");
                    sde.setWedValueOperHist("");
                    sde.setThursValue("");
                    sde.setThursValueOperHist("");
                    sde.setFriValue("");
                    sde.setFriValueOperHist("");
                    sde.setSatValue("");
                    sde.setSatValueOperHist("");
                    sde.setSunValue("");
                    sde.setSunValueOperHist("");
                    sde.setCreator("auto");
                    sde.setCreatedAt(new Date());
                    scheduleDetailsDao.save(sde);
                }
            }else {
                log.info("本周已有日程,定时生成停止");
            }
        }
    }

    public ScheduleEntity create(ScheduleParameter parameter) {
        final UserEntity loginUser = getLoginUser();
//        final UserEntity user = userDao.getByUserId(loginUser.getUserId());
        ScheduleEntity schedule = new ScheduleEntity();
        BeanUtils.copyProperties(parameter, schedule);
        schedule.setCreator(loginUser.getUserName());
        schedule.setCreatedAt(new Date());
        scheduleDao.save(schedule);
        //根据type判断生成名头
        if (parameter.getType() == 0){
            final String[] importPeopleList = importPeople.split(",");
            for (String people : importPeopleList){
                ScheduleDetailsEntity sde = new ScheduleDetailsEntity();
                sde.setScheName(people);
                sde.setScheNameOperHist("");
                sde.setScheduleId(schedule.getId());
                sde.setMonValue("");
                sde.setMonValueOperHist("");
                sde.setTuesValue("");
                sde.setTuesValueOperHist("");
                sde.setWedValue("");
                sde.setWedValueOperHist("");
                sde.setThursValue("");
                sde.setThursValueOperHist("");
                sde.setFriValue("");
                sde.setFriValueOperHist("");
                sde.setSatValue("");
                sde.setSatValueOperHist("");
                sde.setSunValue("");
                sde.setSunValueOperHist("");
                sde.setCreator(loginUser.getUserName());
                sde.setCreatedAt(new Date());
                scheduleDetailsDao.save(sde);
            }
        }else {
            final String[] normalPeopleList = normalPeople.split(",");
            for (String people : normalPeopleList){
                ScheduleDetailsEntity sde = new ScheduleDetailsEntity();
                sde.setScheName(people);
                sde.setScheNameOperHist("");
                sde.setScheduleId(schedule.getId());
                sde.setMonValue("");
                sde.setMonValueOperHist("");
                sde.setTuesValue("");
                sde.setTuesValueOperHist("");
                sde.setWedValue("");
                sde.setWedValueOperHist("");
                sde.setThursValue("");
                sde.setThursValueOperHist("");
                sde.setFriValue("");
                sde.setFriValueOperHist("");
                sde.setSatValue("");
                sde.setSatValueOperHist("");
                sde.setSunValue("");
                sde.setSunValueOperHist("");
                sde.setCreator(loginUser.getUserName());
                sde.setCreatedAt(new Date());
                scheduleDetailsDao.save(sde);
            }
        }
        return schedule;
    }

    public ScheduleEntity initCreate(ScheduleParameter parameter) {
//        final UserEntity loginUser = getLoginUser();
//        final UserEntity user = userDao.getByUserId(loginUser.getUserId());
        ScheduleEntity schedule = new ScheduleEntity();
        BeanUtils.copyProperties(parameter, schedule);
        schedule.setCreator("auto");
        schedule.setCreatedAt(new Date());
        scheduleDao.save(schedule);
        //根据type判断生成名头
        if (parameter.getType() == 0){
            final String[] importPeopleList = importPeople.split(",");
            for (String people : importPeopleList){
                ScheduleDetailsEntity sde = new ScheduleDetailsEntity();
                sde.setScheName(people);
                sde.setScheNameOperHist("");
                sde.setScheduleId(schedule.getId());
                sde.setMonValue("");
                sde.setMonValueOperHist("");
                sde.setTuesValue("");
                sde.setTuesValueOperHist("");
                sde.setWedValue("");
                sde.setWedValueOperHist("");
                sde.setThursValue("");
                sde.setThursValueOperHist("");
                sde.setFriValue("");
                sde.setFriValueOperHist("");
                sde.setSatValue("");
                sde.setSatValueOperHist("");
                sde.setSunValue("");
                sde.setSunValueOperHist("");
                sde.setCreator("auto");
                sde.setCreatedAt(new Date());
                scheduleDetailsDao.save(sde);
            }
        }else {
            final String[] normalPeopleList = normalPeople.split(",");
            for (String people : normalPeopleList){
                ScheduleDetailsEntity sde = new ScheduleDetailsEntity();
                sde.setScheName(people);
                sde.setScheNameOperHist("");
                sde.setScheduleId(schedule.getId());
                sde.setMonValue("");
                sde.setMonValueOperHist("");
                sde.setTuesValue("");
                sde.setTuesValueOperHist("");
                sde.setWedValue("");
                sde.setWedValueOperHist("");
                sde.setThursValue("");
                sde.setThursValueOperHist("");
                sde.setFriValue("");
                sde.setFriValueOperHist("");
                sde.setSatValue("");
                sde.setSatValueOperHist("");
                sde.setSunValue("");
                sde.setSunValueOperHist("");
                sde.setCreator("auto");
                sde.setCreatedAt(new Date());
                scheduleDetailsDao.save(sde);
            }
        }
        return schedule;
    }
    
    public void modify(String id, ScheduleParameter parameter) {
        final UserEntity loginUser = getLoginUser();
        ScheduleEntity schedule = new ScheduleEntity();
        BeanUtils.copyProperties(parameter, schedule);
        schedule.setId(id);
        schedule.setUpdator(loginUser.getUserName());
        schedule.setUpdateTime(new Date());
        scheduleDao.updateById(schedule);
    }

    public void delete(List<String> ids) {
        final UserEntity loginUser = getLoginUser();
        scheduleDao.removeByIds(ids);
    }
    
    public void deletePhysics(List<String> ids) {
        scheduleDao.removeByIds(ids);
    }

    public void detailInsertgai(List<List<Map<String , Object>>> parameter){
        final UserEntity loginUser = getLoginUser();

        String approvalId = "";
        String scheName = "";
        List<ScheduleDetailsEntity> detailEntityList = new ArrayList<>();
        for (List<Map<String , Object>> hangList : parameter){
            ScheduleDetailsEntity detail = new ScheduleDetailsEntity();
            for (Map<String , Object> value : hangList){
                switch (String.valueOf(value.get("name"))) {
                    case "0":
                        //姓名
                        detail.setScheName(String.valueOf(value.get("value")));
                        detail.setScheNameOperHist(String.valueOf(value.get("msg")));
                        detail.setScheNameUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "1":
                        //周一
                        detail.setMonValue(String.valueOf(value.get("value")));
                        detail.setMonValueOperHist(String.valueOf(value.get("msg")));
                        detail.setMonValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "2":
                        //周二
                        detail.setTuesValue(String.valueOf(value.get("value")));
                        detail.setTuesValueOperHist(String.valueOf(value.get("msg")));
                        detail.setTuesValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "3":
                        //周三
                        detail.setWedValue(String.valueOf(value.get("value")));
                        detail.setWedValueOperHist(String.valueOf(value.get("msg")));
                        detail.setWedValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "4":
                        //周四
                        detail.setThursValue(String.valueOf(value.get("value")));
                        detail.setThursValueOperHist(String.valueOf(value.get("msg")));
                        detail.setThursValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "5":
                        //周五
                        detail.setFriValue(String.valueOf(value.get("value")));
                        detail.setFriValueOperHist(String.valueOf(value.get("msg")));
                        detail.setFriValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "6":
                        //周六
                        detail.setSatValue(String.valueOf(value.get("value")));
                        detail.setSatValueOperHist(String.valueOf(value.get("msg")));
                        detail.setSatValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "7":
                        //周日
                        detail.setSunValue(String.valueOf(value.get("value")));
                        detail.setSunValueOperHist(String.valueOf(value.get("msg")));
                        detail.setSunValueUpdateUser(String.valueOf(value.get("update")));
                        continue;
                    case "8":
                        approvalId = String.valueOf(value.get("value"));
                        continue;
                    case "9":
                        scheName = String.valueOf(value.get("value"));
                        continue;
                }
            }
            detail.setCreator(loginUser.getUserId());
            detail.setCreatedAt(new Date());
            detail.setScheduleId(approvalId);
            detailEntityList.add(detail);
        }
        //删除原来的值
        QueryWrapper<ScheduleDetailsEntity> detailQuery = new QueryWrapper<>();
        detailQuery.eq("SCHEDULE_ID", approvalId);
        scheduleDetailsDao.remove(detailQuery);
        final ScheduleEntity schedule = scheduleDao.getById(approvalId);
        schedule.setScheName(scheName);
        scheduleDao.updateById(schedule);
        for (ScheduleDetailsEntity detail : detailEntityList){
            scheduleDetailsDao.save(detail);
            //修改user的fillOutStatus
            UpdateWrapper<UserEntity> updateWrapper = new UpdateWrapper<UserEntity>()
                    .eq("ID", loginUser.getId()).set("FILL_OUT_STATUS", "1");
            userDao.update(updateWrapper);
        }
    }


    public List<List<Map<String , Object>>> searchDetailNewListGai(String type){
        QueryWrapper<ScheduleEntity> query = new QueryWrapper<ScheduleEntity>();
        query.eq("TYPE" , type);
        query.orderByDesc(CREATED_AT);
        Page<ScheduleEntity> page = page(ScheduleEntity.class, "1", "1");
        scheduleDao.page(page, query);
        List<ScheduleEntity> list = page.getRecords();
        ScheduleEntity schedule = new ScheduleEntity();
        if (!list.isEmpty()){
            schedule = list.get(0);
        }
        List<List<Map<String , Object>>> resultList = new ArrayList<>();
        resultList = searchDetailListGai(schedule.getId());
        return resultList;
    }

    public List<List<Map<String , Object>>> searchDetailListGai(String approvalId) {
        QueryWrapper<ScheduleDetailsEntity> detailQuery = new QueryWrapper<>();
        detailQuery.eq("SCHEDULE_ID", approvalId);
        final List<ScheduleDetailsEntity> detailList = scheduleDetailsDao.list(detailQuery);
        int sort = 1;
        List<List<Map<String , Object>>> list = new ArrayList<>();
        for (ScheduleDetailsEntity detail : detailList) {
            List<Map<String , Object>> hang = new ArrayList<>();

            Map<String , Object> map0 = new HashMap<>();
            map0.put("name" , "0");
            map0.put("value" , detail.getScheName());
            map0.put("msg" , detail.getScheNameOperHist());
            map0.put("update" , detail.getScheNameUpdateUser());
            hang.add(map0);
            Map<String , Object> map1 = new HashMap<>();
            map1.put("name", "1");
            map1.put("value" , detail.getMonValue());
            map1.put("msg" , detail.getMonValueOperHist());
            map1.put("update" , detail.getMonValueUpdateUser());
            hang.add(map1);

            Map<String , Object> map2 = new HashMap<>();
            map2.put("name", "2");
            map2.put("value" , detail.getTuesValue());
            map2.put("msg" , detail.getTuesValueOperHist());
            map2.put("update" , detail.getTuesValueUpdateUser());
            hang.add(map2);

            Map<String , Object> map3 = new HashMap<>();
            map3.put("name", "3");
            map3.put("value" , detail.getWedValue());
            map3.put("msg" , detail.getWedValueOperHist());
            map3.put("update" , detail.getWedValueUpdateUser());
            hang.add(map3);

            Map<String , Object> map4 = new HashMap<>();
            map4.put("name", "4");
            map4.put("value" , detail.getThursValue());
            map4.put("msg" , detail.getThursValueOperHist());
            map4.put("update" , detail.getThursValueUpdateUser());
            hang.add(map4);

            Map<String , Object> map5 = new HashMap<>();
            map5.put("name", "5");
            map5.put("value" , detail.getFriValue());
            map5.put("msg" , detail.getFriValueOperHist());
            map5.put("update" , detail.getFriValueUpdateUser());
            hang.add(map5);

            Map<String , Object> map6 = new HashMap<>();
            map6.put("name", "6");
            map6.put("value" , detail.getSatValue());
            map6.put("msg" , detail.getSatValueOperHist());
            map6.put("update" , detail.getSatValueUpdateUser());
            hang.add(map6);

            Map<String , Object> map7 = new HashMap<>();
            map7.put("name", "7");
            map7.put("value" , detail.getSunValue());
            map7.put("msg" , detail.getSunValueOperHist());
            map7.put("update" , detail.getSunValueUpdateUser());
            hang.add(map7);

            Map<String , Object> map8 = new HashMap<>();
            map8.put("name", "8");
            map8.put("value" , approvalId);
            hang.add(map8);

            Map<String , Object> map9 = new HashMap<>();
            map9.put("name", "9");
            final ScheduleEntity schedule = scheduleDao.getById(approvalId);
            map9.put("value" , schedule.getScheName());
            hang.add(map9);

            list.add(hang);
        }
        return list;
    }

    public List<ScheduleDetailsEntity> searchDetailList(String approvalId) {
        QueryWrapper<ScheduleDetailsEntity> detailQuery = new QueryWrapper<>();
        detailQuery.eq("SCHEDULE_ID", approvalId);
        final List<ScheduleDetailsEntity> detailList = scheduleDetailsDao.list(detailQuery);
        return detailList;
    }

    /**
     * 导出报表
     *
     * @return void
     * @Author mwh
     * @Date 14:25 2023/10/9
     * @Param [file]
     **/
    public void expertDerive(String approvalId, HttpServletResponse response) throws Exception {
        List<ScheduleDetailsEntity> detailList = searchDetailList(approvalId);
        final ScheduleEntity approval = scheduleDao.getById(approvalId);
        SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy-MM-dd");
        final String[] newDate = yearSdf.format(new Date()).split("-");
        try {
            Map<String, Object> param = new HashMap<>();
            param.put("list", detailList);
            param.put("reputation", approval.getScheName());
            final Date weekDate = DateTimeUtil.parse(approval.getBeginTime());
            final List<String> weekString = getWeekString(yearSdf.format(weekDate));
            param.put("monDate", weekString.get(0));
            param.put("tuesDate", weekString.get(1));
            param.put("wedDate", weekString.get(2));
            param.put("thursDate", weekString.get(3));
            param.put("friDate", weekString.get(4));
            param.put("satDate", weekString.get(5));
            param.put("sunDate", weekString.get(6));
            if (approval.getType() == 0){
                param.put("title", "importSchedule");
                TemplateExcelUtils.downLoadExcel("importSchedule", "sche/importSchedule.xlsx", param, response);
            }else {
                param.put("title", "normalSchedule");
                TemplateExcelUtils.downLoadExcel("normalSchedule", "sche/normalSchedule.xlsx", param, response);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public List<String> getWeekString(String beginDate) {
        List<String> weekDayStr = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate nowDay = LocalDate.parse(beginDate , formatter);
        List<LocalDate> weekDays = Arrays.stream(DayOfWeek.values())
                .map(nowDay::with)
                .collect(toList());
        for (LocalDate dateStr : weekDays) {
            weekDayStr.add(dateStr.format(formatter));
        }
        return weekDayStr;
    }

}

